var express = require('express');
var jwt = require('jsonwebtoken');
var router = express.Router();
var {
    User,
    Role,
    Permission,
    UserRole,
    RolePermission,
    VerificationCode
} = require('../model/model');
const SMSClient = require('@alicloud/sms-sdk');
function generateVerificationCode() {
    return Math.floor(100000 + Math.random() * 900000).toString();
}

// 登录 生成双token
router.post('/login', async (req, res) => {
    const { username, password } = req.body;
    const user = await User.find({ username });

    if (user[0] && user[0].password === password) {
        // 建议将 refreshToken 存入数据库（演示只返回给客户端）
        const token = jwt.sign({ userId: user[0]._id }, 'your_secret_key', { expiresIn: '1h' });
        const refreshToken = jwt.sign({ userId: user[0]._id }, 'your_refresh_secret_key', { expiresIn: '7d' });
        // 安全建议：将 refreshToken 存入数据库（这里演示返回给客户端）
        // await User.updateOne({ _id: user[0]._id }, { refreshToken });
        // 更安全的做法：通过 HttpOnly Cookie 返回 refreshToken
        res.cookie('refreshToken', refreshToken, {
            httpOnly: true,
            secure: process.env.NODE_ENV === 'production',
            sameSite: 'strict',
            maxAge: 7 * 24 * 60 * 60 * 1000
        });

        res.json({ token, username });
    } else {
        res.status(401).json({ message: '账号或密码错误' });
    }
});

// 新增 refreshToken 路由
router.post('/refresh-token', async (req, res) => {
    const { refreshToken } = req.body;
    if (!refreshToken) {
        return res.status(401).json({ message: '需要提供刷新令牌' });
    }

    try {
        // 验证 refreshToken（注意使用 refreshToken 的密钥）
        const decoded = jwt.verify(refreshToken, 'your_refresh_secret_key');

        // 检查用户是否存在
        const user = await User.findById(decoded.userId);
        if (!user) return res.status(404).json({ message: '用户不存在' });

        // 生成新的 access token（短效）
        const newToken = jwt.sign(
            { userId: user._id },
            'your_secret_key',
            { expiresIn: '1h' }
        );

        // 生成新的 refreshToken（可选，根据业务需求）
        const newRefreshToken = jwt.sign(
            { userId: user._id },
            'your_refresh_secret_key',
            { expiresIn: '7d' }
        );

        res.json({
            token: newToken,
            refreshToken: newRefreshToken // 如果刷新refreshToken需要返回
        });
    } catch (error) {
        if (error.name === 'TokenExpiredError') {
            return res.status(401).json({ message: '刷新令牌已过期，请重新登录' });
        }
        res.status(403).json({ message: '无效的刷新令牌' });
    }
});

// 定义验证 JWT 令牌的中间件
const verifyToken = (req, res, next) => {
    const token = req.headers['authorization'];
    if (!token) {
        return res.status(403).json({ message: '请登录后再试' });
    }

    jwt.verify(token, 'your_secret_key', async (err, decoded) => {
        if (err) {
            // Token 过期时返回特定状态码
            if (err.name === 'TokenExpiredError') {
                return res.status(401).json({
                    code: 'TOKEN_EXPIRED',
                    message: '令牌已过期'
                });
            }
            return res.status(403).json({ message: '请登录后再试' });
        }
        req.userId = decoded.userId;
        next();
    });
};

// 定义检查用户是否具有指定权限的中间件生成函数
const checkPermission = (permissionName) => {
    console.log(1);

    return async (req, res, next) => {

        try {
            // 根据用户 ID 从用户角色关联表中查找该用户关联的所有角色
            const userRoles = await UserRole.find({ user_id: req.userId }).populate('role_id');
            const roleIds = userRoles.map(userRole => userRole.role_id);

            // 根据角色 ID 从角色权限关联表中查找这些角色关联的所有权限id
            const rolePermissions = await RolePermission.find({ role_id: { $in: roleIds } }).populate('permission_id');

            // 提取用户关联的所有权限列表
            const userPermissions = await Permission.find({ _id: { $in: rolePermissions.map(rolePermission => rolePermission.permission_id) } })
            const userPermissionsNames = userPermissions.map(permission => permission.permission_name);
            // 检查用户是否具有指定的权限
            if (userPermissionsNames.includes(permissionName)) {
                // 如果具有指定权限，调用 next 函数，将请求传递给下一个中间件或路由处理函数
                next();
            } else {
                // 如果不具有指定权限，返回 403 状态码和错误信息
                res.status(403).json({ message: '您不具有该权限' });
            }
        } catch (error) {
            // 如果出现错误，返回 500 状态码和错误信息
            console.log(error);

            res.status(500).json({ message: '出现未知错误' });m 
        }
    };
};

// 定义受保护的接口，需要用户登录并具有 "诊断" 权限才能访问
router.get('/resource', verifyToken, checkPermission('诊断'), (req, res) => {
    // 如果用户通过验证，返回成功信息
    res.json({ message: '请求成功' });
});

// 定义受保护的接口，需要用户登录并具有 "看病" 权限才能访问
router.get('/resource1', verifyToken, checkPermission('看病'), (req, res) => {
    // 如果用户通过验证，返回成功信息
    res.json({ message: '请求成功' });
});

// 登出用户登出时清除 refreshToken
router.post('/logout', verifyToken, async (req, res) => {
    await User.updateOne(
        { _id: req.userId },
        { $unset: { refreshToken: 1 } }
    );
    res.clearCookie('refreshToken');
    res.json({ message: '登出成功' });
});

// 发送验证码接口
router.post('/sendVerificationCode', async (req, res) => {
    const { phone } = req.body;
    console.log(phone)
    try {
        // 生成验证码
        const verificationCode = generateVerificationCode();
        // 模拟发送验证码到手机，实际使用时可调用第三方短信服务
        let smsClient = new SMSClient({
            accessKeyId: 'LTAI5tGvYcwsi9seeFzW3UVY',  //accessKeyId 前面提到要准备的
            secretAccessKey: 'dXVDsN8HZWfZfTiMqvoIpu4zGWnpTm'  //secretAccessKey 前面提到要准备的
        });
        console.log(`发送验证码 ${verificationCode} 到手机 ${phone}`);

        // 将验证码存入数据库，设置有效期（这里简单假设有效期为 5 分钟）
        const expirationTime = new Date(Date.now() + 5 * 60 * 1000);
        await VerificationCode.findOneAndUpdate(
            { phone },
            { code: verificationCode, expirationTime },
            { upsert: true }
        );
        smsClient.sendSMS({
            PhoneNumbers: phone,
            SignName: "璐琦佳慧", //签名名称 前面提到要准备的
            TemplateCode: "SMS_474880856", //模版CODE  前面提到要准备的
            TemplateParam: `{"code":'${verificationCode}'}`, // 短信模板变量对应的实际值，JSON格式
        }).then(result => {
            console.log("result", result)
            let { Code } = result;
            if (Code == 'OK') {
                res.json({
                    code: 0,
                    msg: 'success',
                    sms: verificationCode
                })
                console.log(result)
            }
        }).catch(err => {
            console.log(err);
            res.json({
                code: 1,
                msg: 'fail: ' + err.data.Message
            })
        })
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: '验证码发送失败' });
    }
});

// 通过手机号验证码登录接口
router.post('/loginByPhone', async (req, res) => {
    const { phone, verificationCode } = req.body;
    try {
        // 从数据库中获取验证码信息
        const codeDoc = await VerificationCode.findOne({
            phone,
            code: verificationCode,
            expirationTime: { $gt: new Date() }
        });

        if (!codeDoc) {
            return res.status(401).json({ message: '手机号码或验证码错误' });
        }

        // 验证通过，生成 JWT 令牌
        const user = { phone };
        const token = jwt.sign(user, 'your_secret_key', { expiresIn: '1h' });
        const refreshToken = jwt.sign(user, 'your_refresh_secret_key', { expiresIn: '7d' });

        // 从数据库中获取用户名
        const userDoc = await User.findOne({ phone });
        const username = userDoc ? userDoc.username : null;

        res.status(200).json({ token, refreshToken, username });
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: '登录失败，请稍后重试' });
    }
});

module.exports = router;